﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using ShareIt_MVC3.Models;


namespace ShareIt_MVC3
{
    /// <summary>
    /// Unit-tests für die Klasse clsResourceCollection.cs
    /// </summary>
    [TestClass]
    public class UnitTestResource
    {
        public UnitTestResource()
        {
            // leerer Konstruktor
        }

        private TestContext testContextInstance;

        /// <summary>
        ///Ruft den Textkontext mit Informationen über
        ///den aktuellen Testlauf sowie Funktionalität für diesen auf oder legt diese fest.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Zusätzliche Testattribute
        //
        // Sie können beim Schreiben der Tests folgende zusätzliche Attribute verwenden:
        //
        // Verwenden Sie ClassInitialize, um vor Ausführung des ersten Tests in der Klasse Code auszuführen.
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Verwenden Sie ClassCleanup, um nach Ausführung aller Tests in einer Klasse Code auszuführen.
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Mit TestInitialize können Sie vor jedem einzelnen Test Code ausführen. 
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // Mit TestCleanup können Sie nach jedem einzelnen Test Code ausführen.
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //
        #endregion

        /// <summary>
        /// Test: Read all Resources, insert one, search it in list, delete it again
        /// </summary>
        [TestMethod]
        public void TestInsertDeleteResource()
        {
            int i, c1, c2, c3;
            Console.WriteLine("TestInsertDeleteResource(): Start");
            List<Resource> ResourceList;
            ResourceCollection Resources = new ResourceCollection();
            UserCollection userColl = new UserCollection();
            User testUser = new User()
            {
                Username = "TestUsername",
                Name = "TestName",
                Surname = "TestSurname",
                Address = "TestAddress",
                City = "TestCity",
                ZIP = "12345",
                EMail = "test@test.de",
                IsAdmin = false,
                Active = true,
                Password = "TestPassword",
                Credits = 1
            };
            userColl.InsertUser(testUser);

            Resource testResource = new Resource()
            {
                Active = true,
                Author = "TestAutor",
                Category = "TestCategory",
                Owner = userColl.GetUserByUsername("TestUsername"),
                Title = "TestTitle"
            };

            // read Resource list
            ResourceList = Resources.GetAllResources();
            c1 = ResourceList.Count;
            // insert new Resource object
            i = Resources.InsertResource(testResource);
            Assert.AreEqual(i, 1, "Insert failed");
            Console.WriteLine("TestInsertDeleteResource(): Insert");

            // read Resource list again and check if there is one more in list
            ResourceList = Resources.GetAllResources();
            c2 = ResourceList.Count;
            Assert.AreEqual(c1 + 1, c2);
            // look for Resource object that was just inserted and delete it again
            foreach (Resource p in ResourceList)
            {
                if (p.Title == "TestTitle")
                {
                    i = Resources.DeleteResource(p);
                    Assert.AreEqual(i, 1, "delete Failed!");
                    Console.WriteLine("TestInsertDeleteResource(): Delete");
                }
            }
            // read Resource list again and check if there is one less in list
            ResourceList = Resources.GetAllResources();
            c3 = ResourceList.Count;
            Assert.AreEqual(c1, c3, "Count after Delete wrong!");
            Console.WriteLine("TestInsertDeleteResource(): End");

            // User cleanup
            userColl.DeleteUser(userColl.GetUserByUsername(testUser.Username));

        }

        /// <summary>
        /// Test: Read all Resources, insert one, update it, delete it again
        /// </summary>
        [TestMethod]
        public void TestInsertUpdateDeleteResource()
        {
            int i, c1, c2, c3, pid;
            List<Resource> ResourceList;
            ResourceCollection Resources = new ResourceCollection();
            UserCollection userColl = new UserCollection();
            User testUser = new User()
            {
                Username = "TestUsername",
                Name = "TestName",
                Surname = "TestSurname",
                Address = "TestAddress",
                City = "TestCity",
                ZIP = "12345",
                EMail = "test@test.de",
                IsAdmin = false,
                Active = true,
                Password = "TestPassword",
                Credits = 1
            };
            userColl.InsertUser(testUser);

            Resource testResource = new Resource()
            {
                Active = true,
                Author = "TestAutor",
                Category = "TestCategory",
                Owner = userColl.GetUserByUsername("TestUsername"),
                Title = "TestTitle"
            };

            ResourceList = Resources.GetAllResources();
            c1 = ResourceList.Count;
            i = Resources.InsertResource(testResource);
            Assert.AreEqual(i, 1);
            ResourceList = Resources.GetAllResources();
            c2 = ResourceList.Count;
            Assert.AreEqual(c1 + 1, c2);
            foreach (Resource p in ResourceList)
            {
                if (p.Title == "TestTitle")
                {
                    pid = p.ID;
                    p.Author = "Scott Hanselmann";
                    i = Resources.UpdateResource(p);
                    Assert.AreEqual(i, 1);
                    testResource = Resources.GetResourceByID(pid);
                    Assert.AreEqual(testResource.Title, "TestTitle");
                    Assert.AreEqual(testResource.Author, "Scott Hanselmann");
                    i = Resources.DeleteResource(testResource);
                    Assert.AreEqual(i, 1);
                }
            }

            ResourceList = Resources.GetAllResources();
            c3 = ResourceList.Count;
            Assert.AreEqual(c1, c3);

            // User cleanup
            userColl.DeleteUser(userColl.GetUserByUsername(testUser.Username));
        }

        /// <summary>
        /// test: try to delete non-existent Resource
        /// </summary>
        [TestMethod]
        public void TestDeleteNonExistentResource()
        {
            int i, c1, c2, c3;
            List<Resource> ResourceList;

            Console.WriteLine("TestDeleteNonExistentResource(): Start");
            ResourceCollection Resources = new ResourceCollection();


            Resource testResource = new Resource()
            {
                Active = true,
                Author = "TestAutor",
                Category = "TestCategory",
                Title = "TestTitle"
            };


            ResourceList = Resources.GetAllResources();
            c1 = ResourceList.Count;
            foreach (Resource p in ResourceList)
            {
                if (p.Title == "TestTitle")
                {
                    Assert.Inconclusive("TestDeleteNonExistentResource(): Resource TestName exists already???");
                }
            }
            i = Resources.DeleteResource(testResource);
            Assert.AreEqual(0, i, "TestDeleteNonExistentResource(): DeleteResource unexpected result");
            ResourceList = Resources.GetAllResources();
            c3 = ResourceList.Count;
            Assert.AreEqual(c1, c3, "TestDeleteNonExistentResource(): Count after Delete wrong!");
            Console.WriteLine("TestDeleteNonExistentResource(): End");

        }

    }

}
